/**
 * KopsoxFramework
 * Copyright (C) 2010 Free Software Foundation, Inc. <http://fsf.org/>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kopsox.data.container.impl;

import org.kopsox.data.ContainerDescriptor;

/**
 * This is a immutable implementation of the ContainerDescriptor<br>
 * The Descriptor is created with a builder
 * 
 * @author Konrad Renner - 21.06.2010
 *
 */
public final class ContainerDescriptorImpl implements ContainerDescriptor {
	
	private static final long serialVersionUID = 578884347957961589L;

	public static final String NO_NAME_CONTAINER = "noNameContainer";
	
	private final String name;
	private final String namespace;
	private boolean isAutoValidationEnabled;
	private boolean isAutoErrorDelegationEnabled;
	
	//Caches
	private int hashCode = 0;
	private String stringRepr = null;
	
	
	public ContainerDescriptorImpl(ContainerDescriptorBuilder builder){
		this.name = builder.name;
		this.isAutoValidationEnabled = builder.isAutoValidationEnabled;
		this.namespace = builder.namespace;
		this.isAutoErrorDelegationEnabled = builder.isAutoErrorDelegationEnabled;
	}
	
	/* (non-Javadoc)
	 * @see org.kopsox.data.ContainerDescriptor#isAutomaticErrorDelegationEnabled()
	 */
	@Override
	public boolean isAutomaticErrorDelegationEnabled() {
		return this.isAutoErrorDelegationEnabled;
	}

	/* (non-Javadoc)
	 * @see org.kopsox.data.ContainerDescriptor#setAutomaticErrorDelegation(boolean)
	 */
	@Override
	public void setAutomaticErrorDelegation(boolean flag) {
		this.isAutoErrorDelegationEnabled = flag;
	}

	/* (non-Javadoc)
	 * @see org.kopsox.data.ValueDescriptor#setAutoValidationEnabled()
	 */
	@Override
	public void setAutoValidationEnabled(boolean autoVal) {
		this.isAutoValidationEnabled = autoVal;
	}

	/* (non-Javadoc)
	 * @see org.kopsox.data.ValueDescriptor#getName()
	 */
	@Override
	public String getName() {
		return this.name;
	}

	/* (non-Javadoc)
	 * @see org.kopsox.data.ValueDescriptor#getNamespace()
	 */
	@Override
	public String getNamespace() {
		return this.namespace;
	}

	@Override
	public boolean isAutoValidationEnabled() {
		return this.isAutoValidationEnabled;
	}

	@Override
	public int hashCode() {
		int result = this.hashCode;
		if(result == 0) {
			result = 17;
			final int prime = 31;
			result = prime * result + ((name == null) ? 0 : name.hashCode());
			result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
			
			hashCode = result;
		}
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ContainerDescriptorImpl other = (ContainerDescriptorImpl) obj;
		//if (isAutoValidationEnabled != other.isAutoValidationEnabled)
		//	return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (namespace == null) {
			if (other.namespace != null)
				return false;
		} else if (!namespace.equals(other.namespace))
			return false;
		return true;
	}
	
	@Override
	public String toString(){
		if(stringRepr == null) {
			StringBuilder sb = new StringBuilder();
			sb.append("ContainerDescriptorImpl:{");
			sb.append("name=");
			sb.append(this.name);
			sb.append(",namespace:");
			sb.append(this.namespace);
			sb.append(",isAutoValidationEnabled:");
			sb.append(this.isAutoValidationEnabled);
			sb.append(",isAutoErrorDelegationEnabled:");
			sb.append(this.isAutoErrorDelegationEnabled);
			sb.append('}');
			
			stringRepr = sb.toString();
		}

		return stringRepr;
	}
	
	//Builder
	public static final class ContainerDescriptorBuilder{
		//Required parameter
		protected final String name;
		
		//Optional parameter
		protected String namespace = null;
		protected boolean isAutoValidationEnabled = true;
		protected boolean isAutoErrorDelegationEnabled = true;
		
		public ContainerDescriptorBuilder() {
			this(NO_NAME_CONTAINER);
		}
		
		public ContainerDescriptorBuilder(final String name) {
			if(name == null) {
				this.name = NO_NAME_CONTAINER;
			}else {
				this.name = name;
			}
		}
		
		public ContainerDescriptorBuilder namespace(final String nameSpace) {
			this.namespace = nameSpace;
			return this;
		}
		
		public ContainerDescriptorBuilder isAutoValidationEnabled(final boolean autoValidationEnabled) {
			this.isAutoValidationEnabled = autoValidationEnabled;
			return this;
		}
		
		public ContainerDescriptorBuilder isAutoErrorDelegationEnabled(final boolean flag) {
			this.isAutoErrorDelegationEnabled = flag;
			return this;
		}
		
		public ContainerDescriptorImpl build() {
			return new ContainerDescriptorImpl(this);
		}
	}
}
